package com.kexio.user.service.impl;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.kexio.common.dto.Result;
import com.kexio.common.exception.BusinessException;
import com.kexio.email.entity.EmailRecord;
import com.kexio.email.service.EmailService;
import com.kexio.user.service.EmailVerificationService;

/**
 * 邮箱验证码服务实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
public class EmailVerificationServiceImpl implements EmailVerificationService {
    
    private static final Logger logger = LoggerFactory.getLogger(EmailVerificationServiceImpl.class);
    
    private static final String CODE_PREFIX = "email:code:";
    private static final int CODE_LENGTH = 6;
    private static final int CODE_EXPIRE_MINUTES = 5;
    
    @Autowired(required = false)
    private EmailService emailService;
    
    @Autowired(required = false)
    private StringRedisTemplate stringRedisTemplate;
    
    @Value("${kexio.auth.email-verification.enabled:true}")
    private boolean emailVerificationEnabled;
    
    @Value("${spring.application.name:Kexio Forum}")
    private String appName;
    
    @Override
    public boolean sendVerificationCode(String email) {
        if (!emailVerificationEnabled) {
            logger.debug("邮箱验证功能未启用，跳过发送验证码");
            return true;
        }
        
        if (emailService == null) {
            logger.warn("邮件服务未配置，无法发送验证码");
            return false;
        }
        
        if (stringRedisTemplate == null) {
            logger.warn("Redis未配置，无法存储验证码");
            return false;
        }
        
        if (!StringUtils.hasText(email)) {
            logger.warn("邮箱为空，无法发送验证码");
            return false;
        }
        
        try {
            // 1. 生成6位数字验证码
            String code = generateCode();
            
            // 2. 存储到Redis，5分钟有效期
            String key = CODE_PREFIX + email;
            stringRedisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
            
            // 3. 构造邮件内容
            String subject = String.format("[%s] 邮箱验证码", appName);
            String htmlContent = buildVerificationCodeEmail(code);
            
            // 4. 发送邮件
            Result<EmailRecord> result = emailService.sendHtmlEmail(email, subject, htmlContent);
            
            if (result.isSuccess()) {
                logger.info("验证码邮件发送成功: email={}, code={}", email, code);
                return true;
            } else {
                logger.error("验证码邮件发送失败: email={}, message={}", email, result.getMessage());
                return false;
            }
            
        } catch (Exception e) {
            logger.error("发送验证码异常: email={}, error={}", email, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public boolean verifyCode(String email, String code) {
        if (!emailVerificationEnabled) {
            logger.debug("邮箱验证功能未启用，跳过验证");
            return true;
        }
        
        if (stringRedisTemplate == null) {
            logger.warn("Redis未配置，无法验证验证码");
            throw BusinessException.systemError("验证码功能不可用");
        }
        
        if (!StringUtils.hasText(email) || !StringUtils.hasText(code)) {
            throw BusinessException.invalidParam("email or code", "邮箱或验证码不能为空");
        }
        
        try {
            String key = CODE_PREFIX + email;
            String storedCode = stringRedisTemplate.opsForValue().get(key);
            
            if (storedCode == null) {
                logger.warn("验证码不存在或已过期: email={}", email);
                throw BusinessException.invalidParam("code", "验证码不存在或已过期");
            }
            
            if (!storedCode.equals(code)) {
                logger.warn("验证码错误: email={}, input={}, expected={}", email, code, storedCode);
                throw BusinessException.invalidParam("code", "验证码错误");
            }
            
            // 验证成功后删除验证码（一次性使用）
            stringRedisTemplate.delete(key);
            
            logger.info("验证码验证成功: email={}", email);
            return true;
            
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            logger.error("验证码验证异常: email={}, error={}", email, e.getMessage(), e);
            throw BusinessException.systemError("验证码验证失败");
        }
    }
    
    @Override
    public boolean hasValidCode(String email) {
        if (stringRedisTemplate == null) {
            return false;
        }
        
        if (!StringUtils.hasText(email)) {
            return false;
        }
        
        String key = CODE_PREFIX + email;
        return Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));
    }
    
    /**
     * 生成6位数字验证码
     */
    private String generateCode() {
        Random random = new Random();
        int code = random.nextInt(900000) + 100000; // 100000-999999
        return String.valueOf(code);
    }
    
    /**
     * 构造验证码邮件 HTML 内容
     */
    private String buildVerificationCodeEmail(String code) {
        return String.format(
            "<html>" +
            "<head><style>" +
            "body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; background-color: #f4f4f4; margin: 0; padding: 20px; }" +
            ".container { max-width: 600px; margin: 0 auto; background-color: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }" +
            ".header { background: linear-gradient(135deg, #667eea 0%%, #764ba2 100%%); color: white; padding: 30px; text-align: center; }" +
            ".header h1 { margin: 0; font-size: 28px; }" +
            ".content { padding: 40px 30px; }" +
            ".code-box { background-color: #f8f9fa; border: 2px dashed #409eff; border-radius: 8px; padding: 30px; text-align: center; margin: 30px 0; }" +
            ".code { font-size: 36px; font-weight: bold; color: #409eff; letter-spacing: 8px; font-family: 'Courier New', monospace; }" +
            ".tips { background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; color: #856404; }" +
            ".footer { background-color: #f8f9fa; padding: 20px; text-align: center; color: #6c757d; font-size: 12px; }" +
            "</style></head>" +
            "<body>" +
            "<div class='container'>" +
            "<div class='header'>" +
            "<h1>%s</h1>" +
            "<p style='margin: 10px 0 0 0; font-size: 16px;'>邮箱验证</p>" +
            "</div>" +
            "<div class='content'>" +
            "<p style='font-size: 16px; margin-top: 0;'>您好，</p>" +
            "<p style='font-size: 16px;'>您正在注册 <strong>%s</strong> 账号，请使用以下验证码完成注册：</p>" +
            "<div class='code-box'>" +
            "<div style='font-size: 14px; color: #666; margin-bottom: 15px;'>您的验证码是：</div>" +
            "<div class='code'>%s</div>" +
            "</div>" +
            "<div class='tips'>" +
            "<strong>⚠️ 重要提示：</strong><br>" +
            "• 验证码有效期为 <strong>%d 分钟</strong><br>" +
            "• 请勿将验证码告知他人<br>" +
            "• 如非本人操作，请忽略此邮件" +
            "</div>" +
            "<p style='font-size: 14px; color: #6c757d; margin-bottom: 0;'>如果您没有注册 %s 账号，请忽略此邮件。</p>" +
            "</div>" +
            "<div class='footer'>" +
            "<p style='margin: 0;'>此邮件由系统自动发送，请勿回复</p>" +
            "<p style='margin: 10px 0 0 0;'>© 2023 %s. 保留所有权利</p>" +
            "</div>" +
            "</div>" +
            "</body>" +
            "</html>",
            appName, appName, code, CODE_EXPIRE_MINUTES, appName, appName
        );
    }
}
